home *** CD-ROM | disk | FTP | other *** search
/ PC Home 138 / PC Home issue 138.iso / Software / Essentials / Netscape / nim.xpi / bin / chrome / aim.jar / content / aim / IM.js < prev    next >
Encoding:
Text File  |  2002-10-10  |  33.0 KB  |  1,080 lines

  1. var enterCR_pref_value = false;
  2. var Tab_pref_value = false;
  3. var args;
  4. var message="";
  5. var sendAwayMessage = true;
  6. var showTimestampVal;
  7. var isChatContent = false;
  8. var firstSend = 1;
  9.  
  10. /*
  11.  * IMDocumentStateListener is the listener which the IM compose window uses.
  12.  * NotifyDocumentCreated gets called by the editor whenever there is some change in the
  13.  * compose window. If there is any IM message from the input arguments, then that is added 
  14.  * to the compose window and the send button is enabled.
  15. */
  16.  
  17. var IMDocumentStateListener =
  18. {
  19.   NotifyDocumentCreated: function() 
  20.   {
  21.   setTimeout("sendButtonListeners()",0);
  22.   var nsIPlaintextEditor = Components.interfaces.nsIPlaintextEditor;
  23.   window.editorShell.editor.flags |= nsIPlaintextEditor.eEditorNoCSSMask;
  24.   if ( message != "" ) {
  25.     window.editorShell.InsertText(message);
  26.     EnableSendButton();
  27.   }
  28.  
  29.   },
  30.  
  31.   NotifyDocumentWillBeDestroyed: function() {},
  32.   NotifyDocumentStateChanged:function( isNowDirty ) {
  33.     // If the document is not empty, enable the send button
  34.      if (isNowDirty)
  35.        EnableSendButton();
  36.   }
  37. };
  38.  
  39. /*
  40.  * Function:  KnockKnockAddDenyList()
  41.  * Arguments: None
  42.  * Return: None
  43.  * Description:  This function is called when the user clicks on the deny button in the KnockKnock window.
  44.  * It blocks screen name of the incoming message and closees the dialog window.
  45. */
  46.  
  47. function KnockKnockAddDenyList()
  48. {
  49.   val = cmdPeopleBlock();
  50.   if ( val == true )
  51.     window.close();
  52. }
  53.  
  54. /*
  55.  * Function:  toggleKnockKnockPref()
  56.  * Arguments: None
  57.  * Return: None
  58.  * Description:  This function is called when the user chooses not to display the KnockKnock
  59.  * message window. There is a checkbox in the first KnockKnock window which when checked,
  60.  * sets a pref. Once this pref is set, from next time on, there will nit be KnockKnock again.
  61.  * This function justs sets the pref according to the checkbox value.
  62. */
  63.  
  64. function toggleKnockKnockPref()
  65. {
  66.   var element = document.getElementById("IMKnockKnockCheckbox");
  67.   if (aimPrefsManager() && element.checked == true ) {
  68.     aimPrefsManager().SetBoolPref("aim.privacy.knockknock", false , null, false);
  69.   }
  70.   else if ( aimPrefsManager() && element ) {
  71.     aimPrefsManager().SetBoolPref("aim.privacy.knockknock", true , null, false);
  72.   }
  73. }
  74.  
  75. /*
  76.  * Function:  pokeKnockKnockMessage( scname )
  77.  * Arguments: scname
  78.  * Return: None
  79.  * Description:  This function is called when there is a incoming KnockKnock message. It adds the 
  80.  * necessary text to the knockknock window including the sender's screen name and their current warning percent.
  81.  * The sender's screen name is obtained from the input parameter scname. The warning level of sender is obtained
  82.  * by using the locatemanager. It puts up a Ok and Cancel button. clicking Ok will open a Im indow by calling the 
  83.  * StartConveration function (See below). It also checks the KnockKnock pref to see if it has been set or not
  84.  * and updates the checkbox in window.
  85. */
  86.  
  87. function pokeKnockKnockMessage(scname)
  88. {
  89.   var msg = aimString("knock.msg");
  90.   var warning = aimString("knock.warning");
  91.   var message = aimString("knock.preamble").replace(/%ScreenName%/, scname); 
  92.  
  93.   var element = document.getElementById("IMKnockKnockHtml");
  94.   var textNode = document.createTextNode(message);
  95.   element.appendChild(textNode);
  96.  
  97.   element = document.getElementById("IMKnockKnockMessage");
  98.   textNode = document.createTextNode(msg);
  99.   element.appendChild(textNode);
  100.  
  101.   document.getElementById("IMKnockKnockWarningTitle").setAttribute("label", scname);
  102.  
  103.   var locateManager = aimLocateManager();
  104.   var LocateCallbackObject = new Object();
  105.  
  106.   LocateCallbackObject.OnRequestUserInfoDefaultComplete = function(screenname, userobj)
  107.   {
  108.     var element = document.getElementById("IMKnockKnockWarning");
  109.     var percent = userobj.GetWarningPercent();
  110.     var message = warning.replace(/%Level%/,  percent);
  111.     document.getElementById("IMKnockKnockWarning").value = message;
  112.   }
  113.  
  114.   LocateCallbackObject.OnRequestUserInfoDefaultError = function(screenname, error)
  115.   {
  116.     // do nothing
  117.   }
  118.  
  119.   locateManager.RequestUserInfoDefault( LocateCallbackObject, scname );   
  120.  
  121.   labels = document.getElementById("okCancelButtons");
  122.   element = document.getElementById("ok");
  123.   element.setAttribute("label", labels.getAttribute("button1Label"));
  124.   element = document.getElementById("cancel");
  125.   element.setAttribute("label", labels.getAttribute("button2Label"));
  126.  
  127.   doSetOKCancel(StartConversation, CancelConversation);
  128.  
  129.   element = document.getElementById("IMKnockKnockCheckbox");
  130.   var currentVal = aimPrefsManager().GetBoolPref("aim.privacy.knockknock" ,null,false);
  131.   if ( currentVal == true ) 
  132.     element.setAttribute("checked", false);
  133.   else 
  134.     element.setAttribute("checked", true);
  135. }
  136.  
  137. /*
  138. * gFirstTime is a global to determine if our onload handler has been called yet.
  139. * For some reason, our onunload handler is getting called before onload
  140. * on the first time we create IM.xul. This is a workaround.
  141. */
  142.  
  143. var gFirstTime = 1;
  144.  
  145. /*
  146.  * Function:  AimIMOnWndLoad()
  147.  * Arguments: None
  148.  * Return: None
  149.  * Description:  Onload handler for IM conversation window. It creates a IM Object which is 
  150.  * used to store all the focus information and initialises it. It also retrieves the IM Mode and
  151.  * screen name from the window arguments. It adds an event listener to capture keypress events 
  152.  * which gets handles by ComposeKeyPress handler. This is in place to take care of IM specific keydown
  153.  * handling like tab and enter key. If it is knockKnock mode then PokeKnockKnockMessage function (See Above)
  154.  * gets called. Otherwise call StartConversation function ( See Below) brings up the IM window.
  155. */
  156.  
  157. function AimIMOnWndLoad()
  158. {
  159.   gFirstTime = 0;
  160.  
  161.   top.imObject = new Object();
  162.   top.imObject.logHasFocus = false;
  163.   top.imObject.editorHasFocus = false;   
  164.   top.imObject.screenNameHasFocus = false;
  165.    
  166.   /**
  167.    * retrieve window arguments, extract IM mode and screen name
  168.    */
  169.  
  170.   args = aimGetArgs(top.arguments[0]);
  171.   top.document.getElementById("IMAttribs").setAttribute("imMode", args.Mode);
  172.  
  173.   /* capture some events, BEFORE editor does */
  174.  
  175.   var bbox = document.getElementById("ComposeWnd");
  176.   if (bbox) { 
  177.     // bugscape bug 10832, Macintosh is not receiveing the keydown properly.
  178.     if (navigator.appVersion.indexOf("Macintosh") != -1)
  179.       bbox.addEventListener("keypress", composeKeyPress, true);
  180.     else
  181.       bbox.addEventListener("keydown", composeKeyPress, true);
  182.   }
  183.     
  184.  
  185.   // set initial timestamp value for this window, and seed the menu item
  186.  
  187.   showTimestampVal = aimPrefsManager().GetBoolPref("aim.general.im.timeStamp", 
  188.     null, false);
  189.  
  190.   SetTimestampMenuItem();
  191.  
  192.   updateCurrentComposeWindow();
  193.  
  194.   window.setTimeout('delayedOnWndLoad()', 0);
  195. }
  196.  
  197. /*
  198.  * Name: delayedOnWndLoad
  199.  * Arguments: None
  200.  * Description: This is code that logically belongs to AimIMOnWndLoad.
  201.  * It must executed after AimIMOnWndLoad has returned to its caller.
  202.  * This was necessary to make the code in this function work. For some
  203.  * reason it did not work when it was placed directly in AimIMOnWndLoad.
  204.  * The theory is, this is caused by the callback mechanism used in this function,
  205.  * which conflicts with the call frame in which AimIMOnWndLoad is executed.
  206.  * Return Value: None
  207.  * Original Code: portions moved from AimIMOnWndLoad, portions Kai Engert 10/2001
  208.  *
  209.  */
  210. function delayedOnWndLoad()
  211. {
  212.   function CapabitiliesObtainer()
  213.   {
  214.   }
  215.  
  216.   CapabitiliesObtainer.prototype = {
  217.  
  218.     OnRequestUserInfoCapabilitiesError: function(aScreenName, ErrMsg)
  219.     {
  220.       // Unable to obtain, do not enable encryption
  221.     },
  222.  
  223.     OnRequestUserInfoCapabilitiesComplete: function(aScreenName, aUserObj)
  224.     {
  225.       var capMask = aUserObj.GetCapabilities();
  226.       var capEnums = Components.interfaces.nsAimCapabilitesMask;
  227.       if (capEnums.secureIM & capMask) {
  228.         var btnLock = document.getElementById("btnLock");
  229.         if (btnLock) {
  230.           btnLock.removeAttribute("hidden");
  231.         }
  232.         /* we don't want to show it, but we use it to keep track of a window's encryption status*/
  233.         var chkboxCrypt = document.getElementById("chkboxCrypt");
  234.         if (chkboxCrypt) {
  235.           chkboxCrypt.checked = true;
  236.           //chkboxCrypt.removeAttribute("hidden");
  237.         }
  238.         var encryptStatus = document.getElementById("encryptStatus");
  239.         if (encryptStatus) {
  240.           encryptStatus.removeAttribute("hidden");
  241.         }
  242.       }
  243.     }
  244.   }
  245.  
  246.   args = aimGetArgs(top.arguments[0]);
  247.  
  248.   var locateMgr = aimLocateManager();
  249.   if (locateMgr) {
  250.     try {
  251.       var obtainer = new CapabitiliesObtainer();
  252.       locateMgr.RequestUserInfoCapabilities(obtainer, args.ScreenName);
  253.     } catch (ex) {
  254.       dump("* ERROR: unable to retrieve AIM user capabilities for '"+args.ScreenName+"'\n* REASON: " + ex);
  255.     }
  256.   }
  257.  
  258.   /**
  259.    * if knock knock, let user approve it, also, check to see if we should
  260.    * autoreply, and do so if necessary
  261.    */
  262.  
  263.   var pPAimIM = aimPIMObject();
  264.   var screenName = AimIMGetFormScreenName();
  265.   aimIM().SetIMWndIcon(screenName);
  266.  
  267.   if ( args.Mode == "KnockKnock" ) {
  268.     pokeKnockKnockMessage( screenName ); 
  269.   /**
  270.    * we have to set this focus or ok/cancel buttons will not work
  271.    * with the key equivalents. lame
  272.    */
  273.     setTimeout('window.focus()',300);
  274.     return;
  275.   }
  276.   else
  277.     doSetOKCancel(DoNothing, DoNothing);
  278.  
  279.   /**
  280.    * otherwise, do what we have always done
  281.    */
  282.   StartConversation();
  283. }
  284.  
  285. function composeKeyPress(event){
  286.   if (event.keyCode == 46 || event.keyCode == 8)
  287.   {
  288.     /* If user hits backspace or delete key, check if the document will be emptied*/
  289.      checkToDisable();
  290.      return;
  291.   }
  292.         
  293.   // This is how it really should be for control enter 
  294.   // if ((event.ctrlKey) && (event.keyCode == 13))
  295.   // Temporary hack since the above fails. Currently this condition is met by both control-enter 
  296.   // and control-j (Depends bug). Control-j should not send IM -bug tracked in 9007.
  297.   if ((event.ctrlKey) && (event.charCode == 106)) 
  298.   {
  299.      event.preventBubble();
  300.      event.preventDefault();
  301.      if (!window.editorShell.documentIsEmpty)
  302.        window.setTimeout('AimIMCmdSend()', 1, true); 
  303.      return false;
  304.    }
  305.    if ((event.keyCode == 13) || (event.keyCode == 10)){ 
  306.       if (event.shiftKey)
  307.          return;
  308.       if (SendOnEnter() == true) { 
  309.          event.preventBubble();
  310.          event.preventDefault();
  311.          /* Make sure user is not sending a empty message */
  312.          if (!window.editorShell.documentIsEmpty)
  313.             window.setTimeout('AimIMCmdSend(true)', 1, true); 
  314.          return false; 
  315.        } 
  316.        
  317.       return true;
  318.    } 
  319.    if (event.keyCode == 9) {
  320.     if (OnTab() == true) { 
  321.       if (!window.editorShell.documentIsEmpty) {
  322.         document.getElementById('btnSend').focus();
  323.         FocusSend();
  324.        }
  325.        else{
  326.         //send focus to the right field
  327.          var theLogWindow = document.getElementById('LogWnd');
  328.          var theScreenNameField = document.getElementById('fldScreenName')
  329.          var theWindow = document.getElementById('AimIM');
  330.          var theWindowMode = theWindow.getAttribute("imMode")
  331.         if(theWindowMode == "Normal") {
  332.            theScreenNameField.focus();
  333.         }
  334.         if(theWindowMode == "Bound") {
  335.           top.frames['LogWnd'].focus();
  336.         }
  337.        }
  338.       event.preventDefault();
  339.       return false;
  340.  
  341.     } 
  342.     return true;                
  343.    }
  344.    composeSendButtonUpdate();  
  345. }
  346.  
  347. function checkToDisable()
  348. {
  349.   var origLength=window.editorShell.documentLength;
  350.   /* If there is only one element in the document and the user chooses to delete that element,
  351. then the document will be emptied. Disable send button in this case */      
  352.   if (origLength == 1)
  353.   {
  354.     DisableSendButton();
  355.     return;
  356.   }
  357.   var selection=editorShell.editorSelection;
  358.   if (!selection)
  359.     return;
  360.   var tempString=new String(selection);
  361.   var selectLength=tempString.length;
  362.   /* If the user chooses to delete all or more than the contents of the document, 
  363. then the document will be emptied. Disable send button in this case */      
  364.   if (origLength <= selectLength)
  365.   {
  366.     DisableSendButton();
  367.     return;
  368.   }
  369. }
  370.  
  371. function composeMenuPaste()
  372. {
  373.   /* If the user chooses Edit->Paste, this function gets called.
  374.   This will enable the send button if the user is online */
  375.   
  376.   var isOnline= aimSession().IsOnline();
  377.   if (isOnline) 
  378.     EnableSendButton();   
  379. }
  380. function composeSendButtonUpdate() {
  381.   // Give time for editorShell to update the document after mosue events
  382.   setTimeout("checkcomposeSend()", 300);
  383. }
  384.  
  385. function checkcomposeSend()
  386. {
  387.  
  388.   if (!window.editorShell.documentIsEmpty)
  389.      EnableSendButton();
  390.   else 
  391.      DisableSendButton();
  392.    
  393. }
  394.  
  395. function DoNothing()
  396. {
  397.   return false;
  398. }
  399.  
  400. function CancelConversation()
  401. {
  402.     args = aimGetArgs(top.arguments[0]);
  403.     var screenName = AimIMGetFormScreenName();
  404.     var session = aimSession();
  405.     if ( session ) {
  406.       session.AddKnockKnockReject(screenName);
  407.     }
  408.     window.close();
  409. }
  410.  
  411. function StartConversation()
  412. {
  413.   doSetOKCancel(DoNothing, DoNothing);
  414.     args = aimGetArgs(top.arguments[0]);
  415.     var screenName;
  416.     var displayName; 
  417.   
  418.   var isKnockKnock = false;
  419.     if(args.ScreenName)
  420.         screenName= args.ScreenName;
  421.     else
  422.         screenName = "";
  423.     
  424.     if(args.DisplayName)
  425.       displayName= args.DisplayName;
  426.     else
  427.       displayName = "";
  428.  
  429.     if(args.Message) {
  430.         message= args.Message;
  431.   }
  432.     else
  433.         message = "";
  434.     
  435.   if ( args.Mode == "KnockKnock" ) {
  436.     var session = aimSession();
  437.     if ( session ) {
  438.       session.AddKnockKnockAccept(screenName);
  439.     }
  440.     args.Mode = "Bound";
  441.     isKnockKnock = true;
  442.     if ( AimOnlineAway())
  443.       ComeBack();   // return from away state if we are in it
  444.   }
  445.   
  446.   top.document.getElementById("IMAttribs").setAttribute("imMode", args.Mode);
  447.   top.imObject.logHasFocus = false;
  448.   //top.imObject.editorHasFocus = true;   /* XXX */
  449.  
  450.   var editorElement = document.getElementById("ComposeWnd");
  451.   if (!editorElement) {
  452.     return;
  453.   }
  454.   
  455.   var editorShell = editorElement.editorShell;
  456.   if (!editorShell) {
  457.     return;
  458.   }
  459.  
  460.   if(editorShell) {     
  461.     // save the editorShell in the window. The editor JS expects to find it there.
  462.     editorShell.RegisterDocumentStateListener( IMDocumentStateListener );
  463.     window.editorShell = editorShell;
  464.  
  465.     window.editorShell.editorType = "html";
  466.     window.editorShell.webShellWindow = window;
  467.     window.editorShell.contentWindow = window._content;
  468.     
  469.     window.editorShell.LoadUrl("about:blank");
  470.     EditorSharedStartup();
  471.   }
  472.  
  473.   top.document.getElementById("fldScreenName").value = screenName;
  474.   top.document.getElementById("fldDisplayName").value = displayName;
  475.  
  476.     // if we have a screen name, put the focus on the content window
  477.     // otherwise, put the focus in the "To:" field
  478.  
  479.   if(screenName != "") {
  480. //    setTimeout('contentWindow.focus()',300);
  481.     top.imObject.editorHasFocus = true; 
  482.     LoadBuddyIcon(screenName);
  483.   }
  484.   else {
  485.     //setTimeout('top.document.getElementById("fldScreenName").focus()', 350);
  486.       setTimeout("DoFocusAdjust()",200);
  487.       
  488.   }
  489.     
  490.   AimIMSetFormScreenName(screenName, displayName);
  491.   // XXX For some reason, we need to refresh the title after the
  492.   // onload handler or it won't change
  493.   setTimeout('AimIMRefreshScreenName()', 10);
  494.  
  495.   SetTimestampMenuItem();
  496.  
  497.   // since we overlay the edit menu from the editorOverlay.xul file,
  498.   // we have to reset the oncommad to be AIM specific
  499.  
  500.   var pPAimIM = aimPIMObject();
  501.   if(pPAimIM) {
  502.     if(args.setWantBI)
  503.       pPAimIM.OnWindowLoad(screenName, top, sendAwayMessage, true);
  504.     else
  505.       pPAimIM.OnWindowLoad(screenName, top, sendAwayMessage, false);
  506.     if ( sendAwayMessage == true ) {
  507.       var curVal = aimPrefsManager().GetBoolPref("aim.away.autoreply", null, false);
  508.             if ( curVal == true )
  509.         pPAimIM.SendAwayMessageMaybe(AimIMGetFormScreenName(), top);
  510.       sendAwayMessage = false;
  511.     }
  512.   }
  513.   
  514. var DocumentStateListener =
  515. {
  516.   NotifyDocumentCreated: function()
  517.   {
  518.     //see bugzilla bug 112960 for why we have a timeout call
  519.     setTimeout("setStyles()", 100);
  520.   },
  521.   NotifyDocumentWillBeDestroyed: function() {},
  522.   NotifyDocumentStateChanged:function( isNowDirty ) {}
  523. };
  524.  
  525.   // add a listener to be called when the editor is really done loading
  526.   editorShell.RegisterDocumentStateListener( DocumentStateListener );
  527.  
  528. /*
  529.   var theLogNode = top.frames['LogWnd'];
  530.   var myRange = theLogNode.document.createRange();
  531.   var theLogHead = theLogNode.document.getElementsByTagName("head").item(0);
  532.   myRange.setStartAfter(theLogHead);
  533.   var docFrag;
  534.   docFrag = myRange.createContextualFragment("<style type='text/css'>body.timestampHidden span.logtimestamp { display: none}</style>");
  535.   theLogHead.appendChild(docFrag);
  536. */
  537.  
  538.   return false;
  539. }
  540.  
  541. function DoFocusAdjust()
  542. {
  543.   var ScrElement=document.getElementById("fldScreenName");
  544.   if (top.imObject.screenNameHasFocus == false)
  545.     setTimeout("DoFocusAdjust()",100);
  546.   if (ScrElement.value == "")
  547.   {
  548.     ScrElement.focus();
  549.     top.imObject.screenNameHasFocus=true;
  550.     return;
  551.   }
  552.  
  553. }
  554. function AimIMOnWndUnload()
  555. {
  556.   // XXX See note at the top of the file
  557.   if(gFirstTime == 1)
  558.     return;
  559.   var screenName = AimIMGetFormScreenName();
  560.   var pPAimIM = aimPIMObject();
  561.   if(pPAimIM)
  562.     pPAimIM.OnWindowUnload(screenName, top);
  563. }
  564.  
  565. function AimIMCmdSend( strip )
  566. {
  567.   AimIMSetFormAction(true);
  568.   var isOnline= aimSession().IsOnline();
  569.   if (isOnline == false) {
  570.     if (isIcq() == false) {
  571.       aimErrorBox(aimString("msg.LogInToSendIM"));
  572.     }
  573.     else {
  574.       aimErrorBox(aimString("msg.LogInToSendIM_ICQ"));
  575.     }
  576.     toOpenWindowByType('Aim:AimApp', 'chrome://aim/content/App.xul');
  577.     return false;
  578.   }
  579.   var screenName = AimIMGetFormScreenName();
  580.   var displayName = AimIMGetFormDisplayName();
  581.  
  582.   if ( !screenName || screenName == "" ) {
  583.     aimErrorBox(aimString("msg.EmptyScreenName"));
  584.     top.document.getElementById("fldScreenName").focus();
  585.     return false;
  586.   }
  587.   if(false == AimIMIsBound() ) {
  588.     // XXX Should be handled when blur works.
  589.     AimIMSetFormScreenName(top.document.getElementById("fldScreenName").value, top.document.getElementById("fldDisplayName").value);
  590.     screenName = AimIMGetFormScreenName();
  591.  
  592.   }
  593.   if (top.editorShell.documentLength >1024)
  594.   {
  595.     aimErrorBox(aimString("msg.BigIM").replace(/%BigBy%/, ""+(top.editorShell.documentLength-1024)));
  596.     return;
  597.   }
  598.   
  599.   var bodyText;
  600.   var plainBodyText = null;
  601.   var isUnification=getPreaknessFlag();
  602.   if ((aimPrefsManager().GetSessionType()  == 2) || isUnification) {//ICQ
  603.     plainBodyText = top.editorShell.GetContentsAs("text/plain", 2);
  604.     // because of bug in dom text serializer, last call inserts additional new line at the end
  605.     // we need to eliminate it
  606.     plainBodyText = plainBodyText.replace(/\r\n$|\r$|\n$/, "");
  607.   }
  608.  
  609.   bodyText = "<html>" + top.editorShell.GetContentsAs("text/html", 8 + 4) + "</html>";
  610.  
  611.   /* if user hit return, strip out the BR that was added */
  612.  
  613.   bodyText = bodyText.replace(/<\/span><\/span>/g,  " ");
  614.   bodyText = bodyText.replace(/<span class="moz-smiley-s[0-9][0-9]?"><span>/g, " ");
  615.  
  616.   if ( strip == true ) {
  617.     bodyText = bodyText.replace(/<br>/gi, "");
  618.   }
  619.  
  620.   bodyText = bodyText.replace(/\r\n|\r|\n/g, " ");
  621.   bodyText = bodyText.replace(/<big>/gi, "<font size=\"+1\">");
  622.   bodyText = bodyText.replace(/<\/big>/gi, "<\/font>");
  623.   bodyText = bodyText.replace(/<small>/gi, "<font size=\"-1\">");
  624.   bodyText = bodyText.replace(/<\/small>/gi, "<\/font>");
  625.   bodyText = bodyText.replace(/<br><br>/gi, "<br>");
  626.   bodyText = bodyText.replace(/<br><\/body>/i, "<\/body>");
  627.   bodyText = bodyText.replace(/\u00a0/gi, " ");
  628.  
  629.   var backgroundcolor = document.getElementById("cmd_backgroundColor");
  630.   if (backgroundcolor) {
  631.     backgroundcolor = backgroundcolor.getAttribute("state");
  632.     bodyText = bodyText.replace(/<body bgcolor[^>]*>/gi, "<body><font BACK=\"" + backgroundcolor +"\"> ");
  633.     bodyText = bodyText.replace(/<\/body>/gi, "<\/font><\/body>");
  634.   }
  635.  
  636.   if ( AimOnlineAway() )
  637.     ComeBack();   // if away, come back
  638.  
  639.   if (firstSend) {
  640.     //if it is the first msg we are sending...load the BI. This shd execute for only the first outgoing IM.
  641.     LoadBuddyIcon(screenName);
  642.     aimIM().SetIMWndIcon(screenName);
  643.     firstSend = 0;
  644.   }
  645.   aimPIMSendIM(top, screenName, bodyText, plainBodyText);
  646.  
  647.   var session = aimSession();
  648.   if ( session )
  649.     session.AddKnockKnockAccept( screenName );
  650.   
  651.   top.editorShell.SelectAll();
  652.   getStyles();
  653.   top.editorShell.DeleteSelection(null);
  654.         /* After the contents have been emptied, disable the send button*/
  655.   DisableSendButton();
  656.   setStyles();
  657.  
  658.   //*** return focus to editor after clicking send ***
  659.   top._content.focus();
  660.   return true;
  661. }
  662.  
  663. function AimIMIsBound()
  664. {
  665.   var mode = AimIMGetFormMode();
  666.  
  667.   if("Bound" == mode)
  668.     return true;
  669.   return false;
  670. }
  671.  
  672. function AimIMUpdateWarningPercent()
  673. {
  674.   //AimIMUpdateWarningPercent
  675. }
  676.  
  677. //************ Form Accessors ****************
  678.  
  679. function AimIMGetFormMode()
  680. {
  681.   return top.document.getElementById("IMAttribs").getAttribute("imMode");
  682. }
  683.  
  684. function AimIMGetFormScreenName()
  685. {
  686.   //var myScreenName = top.document.getElementById("IMAttribs").getAttribute("imScreenName");
  687.   //if (!myScreenName || myScreenName == "") {
  688.     myScreenName = top.document.getElementById("fldScreenName").value;
  689.     if (!myScreenName || myScreenName == "" || myScreenName == undefined)
  690.       if(args && args.ScreenName)
  691.         myScreenName = args.ScreenName;
  692.   //}
  693.  
  694.   return myScreenName;
  695. }
  696.  
  697. function AimIMGetFormDisplayName()
  698. {
  699.     var myDisplayName = top.document.getElementById("fldDisplayName").value;
  700.     if (!myDisplayName || myDisplayName == "" || myDisplayName == undefined)
  701.       if(args && args.DisplayName)
  702.         myDisplayName = args.DisplayName;
  703.   return myDisplayName;
  704. }
  705.  
  706. function AimIMRefreshScreenName()
  707. {
  708.   AimIMSetFormScreenName(top.document.getElementById('fldScreenName').value, top.document.getElementById('fldDisplayName').value);
  709. }
  710.  
  711. function toKeyPress(event) 
  712. {
  713.    switch(event.keyCode) {
  714.    case 9: 
  715.      if (!event.shiftKey) {
  716.        var SN = top.document.getElementById('fldScreenName').value;
  717.        if (SN && SN != "")
  718.         LoadBuddyIcon(SN);
  719.        window._content.focus();
  720.        event.preventDefault();
  721.      }
  722.      break;
  723.    case 13:
  724.      var SN = top.document.getElementById('fldScreenName').value;
  725.      if (SN && SN != "")
  726.       LoadBuddyIcon(SN);
  727.      window._content.focus();
  728.      break;
  729.    }
  730. }
  731.  
  732.  
  733. function AimIMSetFormScreenName(screenName, displayName)
  734. {
  735.   var pPAimIM = aimPIMObject();
  736.   if(pPAimIM)
  737.     pPAimIM.OnWindowScreenNameChange(screenName, top);
  738.   var title;
  739.  
  740.   if("" == screenName || !screenName) {
  741.     if (isIcq() == true)
  742.       title = aimString("icq.title.Unbound");
  743.     else
  744.       title = aimString("im.title.Unbound");
  745.   }
  746.   else {
  747.     if (isIcq() == true) {
  748.       if ((displayName == "") || (!displayName))
  749.         title = aimString("icq.title.Bound").replace(/%ScreenName%/, screenName);
  750.       else
  751.         title = aimString("icq.title.Bound").replace(/%ScreenName%/, displayName+", "+ screenName);
  752.     }
  753.     else {
  754.       if ((displayName == "") || (!displayName))
  755.       title = aimString("im.title.Bound").replace(/%ScreenName%/, screenName);
  756.       else
  757.         title = aimString("im.title.Bound").replace(/%ScreenName%/, displayName+", "+ screenName);
  758.     }
  759.   }
  760.  
  761.   top.title = title;
  762. }
  763.  
  764. function AimIMSetFormAction(action)
  765. {
  766.   top.document.getElementById("IMAttribs").setAttribute("imAction", action);
  767. }
  768.  
  769. //***********  Window Resizing *****************
  770.  
  771. function AimIMWindowResize(sWidth,sHeight){
  772.   top.resizeTo(sWidth,sHeight)
  773. }
  774.  
  775.  
  776.  
  777. //************  Command Handling ****************
  778.  
  779. function cmdFileNewIM()
  780. {
  781.   aimIMInvokeIMForm(null);
  782. }
  783.  
  784. function cmdEditCut()
  785. {
  786.   if ( top.imObject.editorHasFocus == true  ) {
  787.     EditorCut();
  788.   }
  789. }
  790.  
  791. function cmdEditCopy()
  792. {
  793.   if ( top.imObject.logHasFocus == true ) {
  794.     //Focus window is log wnd
  795.   } 
  796.   else if ( top.imObject.editorHasFocus == true  ) {
  797.     //Focus window is edit wnd
  798.     EditorCopy();
  799.   }
  800. }
  801.  
  802. function cmdEditPaste()
  803. {
  804.   if ( top.imObject.editorHasFocus == true  ) {
  805.   //Focus window is edit wnd
  806.     EditorPaste();
  807.   }
  808. }
  809.  
  810. function cmdEditSelectAll()
  811. {
  812.   if ( top.imObject.logHasFocus == true ) {
  813.     //Focus window is log wnd
  814.   } 
  815.   else if ( top.imObject.editorHasFocus == true  ) {
  816.     //Focus window is edit wnd
  817.     EditorSelectAll();
  818.   }
  819. }
  820.  
  821. function cmdAddressBook()
  822. {
  823.   // XXX DOES THIS STILL WORK, IS IT STILL NEEDED?
  824.   var screenName = AimIMGetFormScreenName();
  825.   var card = aimABInfo().getPersonalAbCardFromAttribute("_AimScreenName", screenName, false);
  826.   // if no card, should we create one?    
  827.   goEditCardDialog("moz-abmdbdirectory://abook.mab", card, null);
  828. }
  829.  
  830. function cmdPeopleSendChatInvitation()
  831. {
  832.   //dump("Implement Menu Command cmdPeopleSendChatInvitation()\n");
  833. }
  834.  
  835.  
  836.  
  837. function cmdPeopleBlock()
  838. {
  839.   var screenName = AimIMGetFormScreenName();
  840.     if( !screenName )
  841.       return false;
  842.   var pIAimPrivacy = aimPrivacy();
  843.   if ( !pIAimPrivacy )
  844.     return false;
  845.   pIAimPrivacy.BlockUser( screenName );
  846.   return true;
  847. }
  848.  
  849. function cmdAddABuddy()
  850. {
  851.   openDialog("chrome://aim/content/BuddyAddBuddy.xul", "", "modal=yes,titlebar,chrome", null, null, AimIMGetFormScreenName());
  852.   
  853. }
  854.  
  855. function cmdCmdWarn()
  856. {
  857.   //dump("Implement Menu Command cmdCmdWarn()\n");
  858. }
  859.  
  860. /**** routines to track Focus */
  861.  
  862. function composeWndFocus(boolval)
  863. {
  864.   if ( top.imObject )
  865.     top.imObject.editorHasFocus = boolval;
  866.   if (boolval) {
  867.     var SN = top.document.getElementById('fldScreenName').value;
  868.     if (SN && SN != "")
  869.       LoadBuddyIcon(SN);
  870.   }
  871. }
  872.  
  873. function logWndFocus(boolval)
  874. {
  875.   if ( top.imObject )
  876.     top.imObject.logHasFocus = boolval;
  877. }
  878.  
  879. function AimIMFldScreenNameFocus(focus)
  880. {
  881.   if(false == focus)
  882.     AimIMSetFormScreenName(top.document.getElementById("fldScreenName").value, top.document.getElementById("fldDisplayName").value);
  883. }
  884.  
  885. function SendOnEnter()
  886. {
  887.   // if enterCR_pref_value is true, the pref was set so that enter was a CR
  888.   // if enterCR_pref_value is false, the user wants enter to send the IM message
  889.   try {
  890.     pref = aimPrefsManager();
  891.     enterCR_pref_value = pref.GetBoolPref("aim.general.im.enterCR", null, false);
  892.   }
  893.   catch (ex) {
  894.     // default to be "send on enter key"
  895.     enterCR_pref_value = true;
  896.   }
  897.   return (!enterCR_pref_value);
  898. }
  899.  
  900. function OnTab()
  901.   try {
  902.     Tab_pref_value = aimPrefsManager().GetBoolPref("aim.general.im.tabKey", null, false);
  903.   }
  904.   catch (ex) {
  905.     // default 
  906.     Tab_pref_value = true;
  907.   }
  908.   return (!Tab_pref_value);
  909. }
  910.  
  911. function EnableSendButton()
  912. {
  913.   top.document.getElementById("btnSend").setAttribute("disabled", "false");
  914. }
  915.  
  916. function DisableSendButton()
  917. {
  918.   top.document.getElementById("btnSend").setAttribute("disabled", "true");
  919.   UnFocusSend();
  920.  
  921. function UnFocusSend()
  922. {
  923.   top.document.getElementById("btnSend").removeAttribute("focus-ring");
  924. }
  925.  
  926. function FocusSend()
  927. {
  928.   top.document.getElementById("btnSend").setAttribute("focus-ring", "true");
  929. }
  930.  
  931. function sendButtonListeners()
  932. {
  933.   /* Add listeners to cut , copy and paste items in menu and context menu */
  934.   var delmenu=document.getElementById("menu_delete");
  935.   if (delmenu)
  936.     delmenu.addEventListener("mouseup", checkToDisable, true);
  937.   var cutmenu=document.getElementById("menu_cut");
  938.   if (cutmenu)
  939.     cutmenu.addEventListener("mouseup", checkToDisable, true);   
  940.   var pastemenu=document.getElementById("menu_paste");
  941.   if (pastemenu)
  942.     pastemenu.addEventListener("mouseup", composeMenuPaste , true);    
  943.   var cmdelmenu=document.getElementById("menu_delete_cm");
  944.   if (cmdelmenu)
  945.     cmdelmenu.addEventListener("mousedown", checkToDisable, true);
  946.   var cmcutmenu=document.getElementById("menu_cut_cm");
  947.   if (cmcutmenu)
  948.     cmcutmenu.addEventListener("mousedown", checkToDisable, true);   
  949.   var cmpastemenu=document.getElementById("menu_paste_cm");
  950.   if (cmpastemenu)
  951.     cmpastemenu.addEventListener("mousedown", composeMenuPaste , true);    
  952.  var bbox = document.getElementById("ComposeWnd");
  953.   if (bbox) {
  954.     bbox.addEventListener("mousedown", composeSendButtonUpdate, true);
  955.     bbox.addEventListener("mouseup", composeSendButtonUpdate, true);
  956.     bbox.addEventListener("dragdrop", composeSendButtonUpdate, true);
  957.    
  958.   }
  959.  
  960. }
  961.  
  962.  
  963. function converseKeyCodeListener()
  964. {
  965.   if (event.keyCode == 13 || event.keyCode == 9) 
  966.   {
  967.     aimAutoCompleteAddress('aimScreenNameType', 'fldScreenName');
  968.     window._content.focus();
  969.     setTimeout('AimIMRefreshScreenName()',50);
  970.     return true;
  971.   } 
  972.   setTimeout('AimIMRefreshScreenName()',50);
  973.   return false;
  974. }
  975.  
  976.  
  977. //////////////////////////////////////////////////////////////////////////////
  978. // IM Log Context Menu helper routines --> The following routines are used by
  979. // the context menu in the IM log overlay...
  980. //////////////////////////////////////////////////////////////////////////////
  981.  
  982. function initializeIMLogContextPane(aContextMenu)
  983. {
  984.   // our base nsContextMenu class is going to take care of enabling/disabliing all our menu items
  985.   // for us. All we need to do is make sure we show and hide the appropriate separators...
  986.  
  987.   aContextMenu.showItem( "context-sep-open", aContextMenu.onSaveableLink || (aContextMenu.inDirList && aContextMenu.onLink));
  988.   aContextMenu.showItem( "context-sep-bookmark", aContextMenu.onLink );
  989.   aContextMenu.showItem( "context-sep-save", aContextMenu.onSaveableLink || aContextMenu.onImage);
  990. }
  991.  
  992.  
  993. function LoadBuddyIcon(screenname)
  994. {
  995.   var aimPrefs = aimPrefsManager();
  996.   if (aimPrefs)
  997.     var biValue = aimPrefs.GetIntPref("aim.buddyicon.displayBuddyIcons", null, false);
  998.   else
  999.     return;
  1000.  
  1001.   //check for Never *display* BI pref before displaying...
  1002.   // 0 - Aceept BI from users in Buddy list.
  1003.   // 1 - Never accept BI
  1004.   // 2 - Never *display* BI's.
  1005.   if (biValue == 2)
  1006.     return;
  1007.   if ((screenname == "") || (screenname == null)) {
  1008.     return;
  1009.   }
  1010.  
  1011.   var nimSession = aimSession();
  1012.   var pictDir = nimSession.profileDir;
  1013.   var biPath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
  1014.   biPath.initWithPath(pictDir.path);
  1015.   biPath.append("picture");
  1016.   if (!biPath.exists()) {
  1017.     return;
  1018.   }
  1019.   biPath.append(screenname+".gif");
  1020.   if (!biPath.exists()) {
  1021.     //The buddy doesn't have BI.
  1022.     return;
  1023.   }
  1024.  
  1025.   var ioService = GetIOService();
  1026.   var bifileurl = ioService.getURLSpecFromFile(biPath);
  1027.     
  1028.   var currentTime = new Date().getTime();
  1029.   var BIfield = top.document.getElementById("BuddyIcon");
  1030.   BIfield.setAttribute("src", bifileurl+"?foobar="+currentTime);
  1031.  
  1032. }
  1033.  
  1034.  
  1035. function GetIOService()
  1036. {
  1037.   var IOService = Components.classes["@mozilla.org/network/io-service;1"]
  1038.                .getService(Components.interfaces.nsIIOService);
  1039.  
  1040.   return IOService;
  1041. }
  1042.  
  1043. function updateCurrentComposeWindow()
  1044. {
  1045.   if (isIcq() == true ) {
  1046.     document.getElementById('icqDisplayFields').setAttribute('hidden', false);
  1047.     document.getElementById('fldDisplayName').setAttribute('hidden', false);
  1048.     var elems = document.getElementById("sessionComposeWatcher");
  1049.     elems.setAttribute("sessionMode", "Icq"); 
  1050.     var icqval=document.getElementById('composetoolbarmenu').getAttribute('icqlabel','value');
  1051.     document.getElementById('composetoolbarmenu').setAttribute('label', icqval);
  1052.     icqval=document.getElementById('AimIM').getAttribute('icqtitle','value');
  1053.     document.getElementById('AimIM').setAttribute('title', icqval);
  1054.     icqval=document.getElementById('menu_newMsg').getAttribute('icqlabel','value');
  1055.     document.getElementById('menu_newMsg').setAttribute('label', icqval);
  1056.     icqval=document.getElementById('menu_peopleadd').getAttribute('icqlabel','value');
  1057.     document.getElementById('menu_peopleadd').setAttribute('label', icqval);
  1058.     icqval=document.getElementById('tbAddBuddy').getAttribute('icqlabel','value');
  1059.     document.getElementById('tbAddBuddy').setAttribute('label', icqval);
  1060.     icqval=document.getElementById('tbAddBuddy').getAttribute('icqtooltip','value');
  1061.     document.getElementById('tbAddBuddy').setAttribute('tooltiptext', icqval);
  1062.     icqval=document.getElementById('tbBlock').getAttribute('icqlabel','value');
  1063.     document.getElementById('tbBlock').setAttribute('label', icqval);
  1064.     icqval=document.getElementById('tbBlock').getAttribute('icqtooltip','value');
  1065.     document.getElementById('tbBlock').setAttribute('tooltiptext', icqval);
  1066.     document.getElementById('formatMenu').setAttribute('hidden', true);
  1067.     icqval=document.getElementById('btnSend').getAttribute('icqtooltip','value');
  1068.     document.getElementById('btnSend').setAttribute('tooltiptext', icqval);
  1069.   }
  1070.   else
  1071.   {
  1072.     // App is aim, hide icq disp stuff
  1073.     document.getElementById('icqDisplayFields').setAttribute('hidden', true);
  1074.     document.getElementById('fldDisplayName').setAttribute('hidden', true);
  1075.   }
  1076. }
  1077.  
  1078.